Particle System has been built using C++ only. UI and player controls has been made in blueprints. User can see pre-defined systems and emitters in interactive showroom. Each presented system can be reset with new parameters.
Before starting of implementation of the system in C++ I had to create a design and define the relationships between classes.
The diagram shows the relationships between particle class and emitter class. New particle class can be inherited from the base class and custom components can be added to inherited particles (additional sprites, 3D meshes etc.) and existing functionality can be extended. Then this predefined class can be selected in emitter settings to use this class instead of default base particle class.
Random Generation
I am using FMath functions to generate random numbers in range. I am using it to randomly generate lifetime and velocity for my Particle. Max and Min values are passed as parameters in Start function
Next, I created Update function where Particle properties such us velocity and color will be updated each frame. Update function will be called by Particle Emitted. I also set Tick function to false for Particle class.
Particle Color Blending
Blending colour rate will be calculated based on the particle lifetime, initial and end colours (defined by user).
The colour of the particle will be changed in each frame. The blend rates for all channels will be multiplied by Delta Time and then subtracted from current values to give a smooth blend effect.
Local And World Space
User can define current space used for particle transformations. Local space will bound the particles to the relative space as the Particle Emitter child actor. Choosing world transform will let the particle to use world coordinates. This can be useful if we would like to make particles transforms independent from Particles Emitter coordinates. Below we can see the same paricle system with identical settings. On the first picture I am using World space coordinates. As we can see Particles use World Z axis instead of Emitter coordinates.
The next picture shows Particles Movement with Local space enabled.
Target Actor To Face
Some systems would require particles or emitter to face particular actor to keep the rotation of particles relative to chosen actor (i.e. player camera).
Updating Particle
Particles will be updated only if Particle System, will call update function on active particle. All transformations logic will take place here. The motion of the particle will be calculated taking into account current velocity, force applied and delta time. As my particles do not have mass, simple subtraction of force from current velocity will provide the final velocity.
Particles Emitter will be responsible for taking input values and pass them to particles. The number of particles to spawn will be calculated based on the Emit Rate (particles to emit in one second) and the maximum particle lifetime. If user did not specify the predefined particle class, the default class will be used (user has to provide the sprite2D).
At the beginning of Tick function, Emitter will check if any actor to face has been specified (check if != nullptr). Based on this the rotation of emitter will be dependent (or not) to specified actor.
I have decided to split particles into two groups: active and inactive. Each frame only active particles will be updated. Particles from Active array will be transferred into NotActive array if current lifetime will be equal or higher than the max lifetime. Based on emit rate, the calculated amount of particles will be set to active and transferred to Active array.
Creating Particles
Particle Emitter can spawn either default or predefined particle. The difference will be only in spawning the particle into the world.